package com.xiexie.seckill.config;

import org.springframework.amqp.core.*;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.HashMap;
import java.util.Map;


/**
 * rabbitMQ 配置类
 */
@Configuration
public class RabbitMQConfig {

    @Bean
    public Queue queue() {
        // 队列名称和是否持久化
        return new Queue("queue", true);
    }

    /************************** fanout模式 start *******************************/
    private static final String QUEUE01 = "queue_fanout01";
    private static final String QUEUE02 = "queue_fanout02";
    private static final String EXCHANGE = "fanoutExchange";

    @Bean
    public Queue queue01() {
        return new Queue(QUEUE01, true);
    }

    @Bean
    public Queue queue02() {
        return new Queue(QUEUE02, true);
    }

    @Bean
    public FanoutExchange fanoutExchange() {
        return new FanoutExchange(EXCHANGE);
    }

    // 将队列绑定到交换机上 广播fanout模式
    // 需要将队列绑定在交换机上 消息直接发送到交换机上然后这个交换机中的队列做配置接收
    @Bean
    public Binding binding01() {
        return BindingBuilder.bind(queue01()).to(fanoutExchange());
    }

    @Bean
    public Binding binding02() {
        return BindingBuilder.bind(queue02()).to(fanoutExchange());
    }
    /************************** fanout模式 end *******************************/


    /************************** direct模式 start *******************************/
    private static final String DIRECT_QUEUE01 = "queue_direct01";
    private static final String DIRECT_QUEUE02 = "queue_direct02";
    private static final String DIRECT_EXCHANGE = "directExchange";
    private static final String DIRECT_ROUTINGKEY01 = "direct.queue.red";
    private static final String DIRECT_ROUTINGKEY02 = "direct.queue.green";

    @Bean
    public Queue directQueue01() {
        return new Queue(DIRECT_QUEUE01, true);
    }

    @Bean
    public Queue directQueue02() {
        return new Queue(DIRECT_QUEUE02, true);
    }

    @Bean
    public DirectExchange directExchange() {
        return new DirectExchange(DIRECT_EXCHANGE);
    }

    // 将队列绑定到交换机上 direct模式 需要绑定路由键
    // 根据路由键来判断交换机的哪一个队列来做处理
    @Bean
    public Binding directBinding01() {
        return BindingBuilder
                .bind(directQueue01())
                .to(directExchange())
                .with(DIRECT_ROUTINGKEY01);
    }

    @Bean
    public Binding directBinding02() {
        return BindingBuilder
                .bind(directQueue02())
                .to(directExchange())
                .with(DIRECT_ROUTINGKEY02);
    }

    /************************** direct模式 end *******************************/

    /************************** topic模式 start *******************************/
    private static final String TOPIC_QUEUE01 = "queue_topic01";
    private static final String TOPIC_QUEUE02 = "queue_topic02";
    private static final String TOPIC_EXCHANGE = "topicExchange";
    // # 可以匹配多个
    private static final String TOPIC_ROUTINGKEY01 = "#.queue.#";
    // * 只可以匹配一个
    private static final String TOPIC_ROUTINGKEY02 = "*.queue.#";

    @Bean
    public Queue topicQueue01() {
        return new Queue(TOPIC_QUEUE01, true);
    }

    @Bean
    public Queue topicQueue02() {
        return new Queue(TOPIC_QUEUE02, true);
    }

    @Bean
    public TopicExchange topicExchange() {
        return new TopicExchange(TOPIC_EXCHANGE);
    }

    // 将队列绑定到交换机上 topic模式 需要绑定路由键（路由键是 # * 通配符模式）
    // 根据路由键来判断交换机的哪一个队列来做处理
    @Bean
    public Binding topicBinding01() {
        return BindingBuilder
                .bind(topicQueue01())
                .to(topicExchange())
                .with(TOPIC_ROUTINGKEY01);
    }

    @Bean
    public Binding topicBinding02() {
        return BindingBuilder
                .bind(topicQueue02())
                .to(topicExchange())
                .with(TOPIC_ROUTINGKEY02);
    }
    /************************** topic模式 end *******************************/

    /************************** headers模式 start *******************************/
    private static final String HEADERS_QUEUE01 = "queue_headers01";
    private static final String HEADERS_QUEUE02 = "queue_headers02";
    private static final String HEADERS_EXCHANGE = "headersExchange";

    @Bean
    public Queue headerQueue01() {
        return new Queue(HEADERS_QUEUE01, true);
    }

    @Bean
    public Queue headerQueue02() {
        return new Queue(HEADERS_QUEUE02, true);
    }

    @Bean
    public HeadersExchange headerExchange() {
        return new HeadersExchange(HEADERS_EXCHANGE);
    }

    // 将队列绑定到交换机上 headers模式 由map键值对来匹配
    @Bean
    public Binding headersBinding01() {
        Map<String, Object> map = new HashMap<>();
        map.put("color", "red");
        map.put("speed", "low");
        return BindingBuilder
                .bind(headerQueue01())
                .to(headerExchange())
                .whereAny(map) // 匹配到上述任意一个
                .match();
    }

    @Bean
    public Binding headersBinding02() {
        Map<String, Object> map = new HashMap<>();
        map.put("color", "red");
        map.put("speed", "fast");
        return BindingBuilder
                .bind(headerQueue02())
                .to(headerExchange())
                .whereAll(map) // 同时匹配上述所有
                .match();
    }
    /************************** headers模式 end *******************************/


    /************************** 秒杀业务 TOPIC模式 start *******************************/
    private static final String SECKILL_QUEUE = "queue_seckill";
    private static final String SECKILL_EXCHANGE = "seckillExchange";

    @Bean
    public Queue seckillQueue() {
        return new Queue(SECKILL_QUEUE, true);
    }

    @Bean
    public TopicExchange seckillExchange() {
        return new TopicExchange(SECKILL_EXCHANGE);
    }

    @Bean
    public Binding seckillBinding() {
        return BindingBuilder.bind(seckillQueue())
                .to(seckillExchange())
                .with("seckill.#");
    }
    /************************** 秒杀业务 end *******************************/

}
